#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import abort, g
from flask_restful import Resource, reqparse, marshal_with, fields
from sqlalchemy import or_, and_

from src.api import api, meta_fields
from src.api.auth import self_only
from src.models.record import Record
from src.models.user import User
from src.helpers import paginate
from src.extensions import auth


record_parser = reqparse.RequestParser()
record_parser.add_argument('title', type=unicode, required=True)
record_parser.add_argument('brief', type=unicode, required=True)
record_parser.add_argument('description', type=unicode, required=True)
record_parser.add_argument('imgBefore', dest='img_before', type=unicode, required=True)
record_parser.add_argument('imgAfter', dest='img_after', type=unicode, required=True)
record_parser.add_argument('descBefore', dest='desc_before', type=unicode, required=False)
record_parser.add_argument('descAfter', dest='desc_after', type=unicode, required=False)
record_parser.add_argument('viewCount', dest='view_count', type=int, required=False)
record_parser.add_argument('recommendCount', dest='recommend_count', type=int, required=False)
record_parser.add_argument('tags', type=unicode, required=False)
record_parser.add_argument('categoryId', dest='category_id', type=int, required=True)
record_parser.add_argument('isShow', dest='is_show', type=int, required=False)

static_parser = reqparse.RequestParser()
static_parser.add_argument('recommendCount', dest='recommend_count', type=int, required=False)
static_parser.add_argument('viewCount', dest='view_count', type=int, required=False)

record_collection_parser = reqparse.RequestParser()
record_collection_parser.add_argument('title', type=str, required=False)
record_collection_parser.add_argument('description', type=str, required=False)
record_collection_parser.add_argument('categoryId', type=int, required=False)


# Marshaled field definitions for task objects
record_fields = {
    'id': fields.Integer,
    'userId': fields.Integer(attribute='user_id'),
    'categoryId': fields.Integer(attribute='category_id'),
    'title': fields.String,
    'brief': fields.String,
    'description': fields.String,
    'imgBefore': fields.String(attribute='img_before'),
    'imgAfter': fields.String(attribute='img_after'),
    'descBefore': fields.String(attribute='desc_before'),
    'descAfter': fields.String(attribute='desc_after'),
    'viewCount': fields.Integer(attribute='view_count'),
    'recommendCount': fields.Integer(attribute='recommend_count'),
    'tags': fields.String,
    'isShow': fields.Integer(attribute='is_show'),
    'createTime': fields.DateTime(attribute='create_time')
}

# Marshaled field definitions for collections of task objects
blog_collection_fields = {
    'items': fields.List(fields.Nested(record_fields)),
    'meta': fields.Nested(meta_fields),
}


class StaticResource(Resource):
    @marshal_with(record_fields)
    def post(self, record_id=None):
        update_record = Record.get_by_id(record_id)
        record = Record.update(update_record, **static_parser.parse_args())
        return record


class RecordResource(Resource):
    @marshal_with(record_fields)
    def get(self, record_id=None):
        record = Record.get_by_id(record_id)

        if not record:
            abort(404)

        return record

    @auth.login_required
    @self_only
    @marshal_with(record_fields)
    def post(self, record_id=None):
        update_record = Record.get_by_id(record_id)
        record = Record.update(update_record, **record_parser.parse_args())
        return record

    @auth.login_required
    @self_only
    def delete(self, blog_id=None):
        update_record = Record.get_by_id(blog_id)
        Record.delete(update_record)
        return 204


class RecordCollectionResource(Resource):

    @marshal_with(blog_collection_fields)
    @paginate()
    def get(self, user_id=None, username=None):
        # Find user that task goes with
        user = None
        if user_id:
            user = User.get_by_id(user_id)
        else:
            user = User.get_by_username(username)

        if not user:
            abort(404)

        # Get the user's records
        # records = Record.query.filter_by(user_id=user.id)

        records = Record.query.filter(or_(Record.is_show == None, Record.is_show == 0)).order_by(Record.id.desc())  # 隐藏的不要

        args = record_collection_parser.parse_args()
        # fancy url argument query filtering!
        if args['categoryId'] is not None:
            records = records.filter_by(category_id=args['categoryId'])

        return records

    @auth.login_required
    @self_only
    @marshal_with(record_fields)
    def post(self, user_id=None, username=None):
        args = record_parser.parse_args()
        # user owns the task
        args['user_id'] = g.user.id
        record = Record.create(**args)
        return record, 201


api.add_resource(StaticResource, '/record/static/<int:record_id>')
api.add_resource(RecordResource, '/record/<int:record_id>')
api.add_resource(RecordCollectionResource, '/user/<int:user_id>/record')
